package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.entity.activity.args.ConditionTypeValueArgs;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.decoration.MammonCongratulateTime;
import com.yanqu.road.entity.decoration.MammonEffectResult;
import com.yanqu.road.entity.decoration.UserMammon;
import com.yanqu.road.entity.decoration.UserMammonDecoration;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.logic.bussiness.player.UserMammonBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.DecorationPb;
import com.yanqu.road.pb.decoration.DecorationProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.task.TaskModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.mammon.MammonMgr;
import com.yanqu.road.server.pb.WorldMessagePb;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MammonModule extends GeneralModule {

    private UserMammon userMammon;

    private RandomHelper threadSafeRandom = new RandomHelper();

    private Map<Integer, Long> lastPushCongratulateRecordTimeMap = new ConcurrentHashMap<>();

    private Map<Integer, UserMammonDecoration> userMammonDecorationMap = new ConcurrentHashMap<>();

    public MammonModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        userMammon = UserMammonBussiness.getUserMammon(player.getUserId());
        userMammonDecorationMap = UserMammonBussiness.getMammonDecoration(player.getUserId());
        return true;
    }

    @Override
    public boolean afterLoadData() {
        if (SystemOpenMgr.systemOpen(player, eSystemId.Mammon.getValue())) {
            initUserMammon();
        }
        return true;
    }

    @Override
    public boolean saveData() {
        if (null != userMammon) {
            if (userMammon.isInsertOption()) {
                UserMammonBussiness.addUserMammon(userMammon);
            } else if (userMammon.isUpdateOption()) {
                UserMammonBussiness.updateUserMammon(userMammon);
            }
        }
        if (null != userMammonDecorationMap) {
            for (UserMammonDecoration userMammonDecoration : userMammonDecorationMap.values()) {
                if (userMammonDecoration.isInsertOption()) {
                    UserMammonBussiness.addUserMammonDecoration(userMammonDecoration);
                } else if (userMammonDecoration.isUpdateOption()) {
                    UserMammonBussiness.updateUserMammonDecoration(userMammonDecoration);
                }
            }
        }

        return true;
    }

    @Override
    public void loginSendMsg() {
        lastPushCongratulateRecordTimeMap = new ConcurrentHashMap<>();
        syncUserMammon();
        if (null != userMammon) {
            syncUserMammonCongratulate(new ArrayList<>(userMammon.getCongratulateTimeMap().values()), true);
        }
        syncMammonCongratulate();
    }

    @Override
    public void afterLogin() {
        checkCreateMammonDecoration();
    }

    /**
     * 检测是否需要创建财神
     */
    public synchronized void checkCreateMammonDecoration(){
        Map<Integer,Integer> taskMaxValueMap = null;
        long holyAdd = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.HolyMammonGetCount);
        for (eMammonType type :eMammonType.values()){
            //圣灵就不管了 不能重复加
            if (type == eMammonType.HolyMammon){
                continue;
            }
            if (!userMammonDecorationMap.containsKey(type.getValue())){
                Map<Integer, List<Integer>> mammonDecorationInfo = GoodsMgr.getMammonDecorationInfo();
                if (mammonDecorationInfo == null || !mammonDecorationInfo.containsKey(type.getValue())){
                    log.error("checkCreateMammonDecoration error,goodMgr no init  MammonType = {}",type.getValue());
                    continue;
                }
                List<Integer> decorationIdList = mammonDecorationInfo.get(type.getValue());
                if (decorationIdList == null || decorationIdList.isEmpty()){
                    log.error("checkCreateMammonDecoration error,goodMgr no init  MammonType = {}",type.getValue());
                    continue;
                }
                int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
                Date timeByChannelId = MammonMgr.getTimeByChannelId(channelId);

                int historyNum = -1;
                try {
                    historyNum = UserMammonBussiness.getUserHistoryMammonDecoration(player.getUserId(),decorationIdList,timeByChannelId);
                }catch (Exception e){
                    e.printStackTrace();
                }
                if (historyNum < 0){
                    log.error("checkCreateMammonDecoration error,getUserHistoryMammonDecoration error  MammonType = {}",type.getValue());
                    continue;
                }
                if (taskMaxValueMap == null){
                    taskMaxValueMap = player.getModule(TaskModule.class).getMaxConditionValue();
                }
                if (taskMaxValueMap.containsKey(type.getValue())){
                    int maxTaskValue = taskMaxValueMap.get(type.getValue());    //拿出最大数值
                    maxTaskValue = maxTaskValue - (int)holyAdd;                 //减去圣灵的
                    if (maxTaskValue > historyNum){                             //如果任务最大数值大于历史数值
                        historyNum = maxTaskValue;                              //就把历史数值设置为任务最大数值
                    }
                }
                UserMammonDecoration decoration = new UserMammonDecoration();
                decoration.setUserId(player.getUserId());
                decoration.setMammonType(type.getValue());
                decoration.setNum(historyNum);
                decoration.setInsertOption();
                userMammonDecorationMap.put(type.getValue(),decoration);
            }
        }
        updateAllMammonTask();
    }

    /**
     * 更新所有类型称号成就
     */
    public void updateAllMammonTask(){
        for (UserMammonDecoration decoration : userMammonDecorationMap.values()){
            updateMammonDecorationTask(decoration);
        }
    }

    /**
     * 更新称号成就
     * @param decoration
     */
    public void updateMammonDecorationTask(UserMammonDecoration decoration){
        if (decoration == null){
            log.error("userId:{} updateMammonTask error,decoration is null",getUserId());
            return;
        }
        long holyAdd = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.HolyMammonGetCount);
        player.notifyListener(eGamePlayerEventType.MammonDecorationCount.getValue(), new ConditionTypeValueArgs(decoration.getMammonType(), decoration.getNum()+(int) holyAdd));

    }

    /**
     * 获取新的财神称号
     */
    public void addMammonDecoration(int type,int num){
        if (type <= 0){
            log.error("userId:{} addMammonDecoration error,type = {}",getUserId(),type);
            return;
        }
        if (userMammonDecorationMap==null || !userMammonDecorationMap.containsKey(type)){
            checkCreateMammonDecoration();
        }

        if (!userMammonDecorationMap.containsKey(type)){
            log.error("userId:{} addMammonDecoration error,not contains type = {}",getUserId(),type);
            return;
        }
        UserMammonDecoration decoration = userMammonDecorationMap.get(type);
        if (decoration == null){
            log.error("userId:{} addMammonDecoration error,decoration is null",getUserId());
            return;
        }
        decoration.setNum(decoration.getNum()+num);
        decoration.setUpdateOption();
        updateMammonDecorationTask(decoration);
    }


    public void resetOneDay() {
        if (null == userMammon) {
            return;
        }
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
        if (userMammon.getResetTime() < zeroTime) {
            userMammon.setEffectTimes(0);
            userMammon.setMammonSkillId(0);
            userMammon.setResetTime(zeroTime);
            syncUserMammon();
        }
    }

    private void syncMammonCongratulate() {
        if (null != userMammon) {//解锁财神庙了才推红点通知
            String param = MammonMgr.getMammonCongratulateRedHotParam(player);
            if (!StringUtils.isNullOrEmpty(param)) {
                WorldMessageProto.RedHotNotifyMsg.Builder redHotMsg = WorldMessagePb.parseRedHotNotifyMsg(eRedHotNotifyType.MammonCanCongratulate.getValue(), 1, param);
                player.sendPacket(Protocol.U_RED_HOT_NOTIFY, redHotMsg);
            }
        }
    }

    public void initMammonSystem() {
        initUserMammon();
        syncUserMammon();
        syncMammonCongratulate();

        // 解锁财神殿称号
        player.getModule(TaskModule.class).addMammonUnlockTask();
    }

    private void initUserMammon() {
        if (null == userMammon) {
            UserMammon tempMammon = new UserMammon();
            tempMammon.setUserId(player.getUserId());
            tempMammon.setMammonSkillId(0);
            tempMammon.setWorshipTime(0);
            tempMammon.setResetTime(LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000);
            tempMammon.setInsertOption();
            userMammon = tempMammon;
        }
    }

    public void syncUserMammon() {
        DecorationProto.MammonDataMsg.Builder msg = DecorationPb.parseMammonDataMsg(userMammon);
        if (null != msg) {
            player.sendPacket(Protocol.U_MAMMON_DATA_SYNC, msg);
        }
    }

    private void syncUserMammonCongratulate(MammonCongratulateTime mammonCongratulateTime) {
        if (null != mammonCongratulateTime) {
            List<MammonCongratulateTime> syncList = new ArrayList<>();
            syncList.add(mammonCongratulateTime);
            syncUserMammonCongratulate(syncList, false);
        }
    }

    private void syncUserMammonCongratulate(List<MammonCongratulateTime> congratulateTimeList, boolean isLogin) {
        if (isLogin) {
            player.sendPacket(Protocol.U_MAMMON_CONGRATULATE_DATA_LIST, DecorationPb.parseMammonCongratulateDataListMsg(congratulateTimeList));
        } else {
            player.sendPacket(Protocol.U_MAMMON_CONGRATULATE_DATA_SYNC, DecorationPb.parseMammonCongratulateDataListMsg(congratulateTimeList));
        }
    }

    /**
     * 是否恭贺过记录时间点的财神簿
     *
     * @param type
     * @param recordTime
     * @return
     */
    public boolean isMammonCongratulate(int type, long recordTime) {
        if (null == userMammon) {
            return true;
        }
        MammonCongratulateTime mammonCongratulateTime = userMammon.getCongratulateTime(type);
        if (null == mammonCongratulateTime) {
            return false;
        }
        if (mammonCongratulateTime.getRecordTime() >= recordTime) {
            return true;
        }
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
        return mammonCongratulateTime.getCongratulateTime() >= zeroTime;
    }

    /**
     * 需要推送红点
     *
     * @param type
     * @param recordTime
     * @return
     */
    public boolean needPushRedHot(int type, long recordTime) {
        if (null == userMammon) {
            return false;
        }
        if (isMammonCongratulate(type, recordTime)) {
            return false;
        }
        if (System.currentTimeMillis() / 1000 - recordTime > GameConfig.MAMMON_CAN_CONGRATULATE_TIME * DateHelper.HOUR_SECONDS) {
            return false;
        }
        if (isInCongratulateCD(type)) {
            return false;
        }
        long lastPushCongratulateRecordTime = getLastPushCongratulateRecordTime(type);
        if (recordTime <= lastPushCongratulateRecordTime) {
            return false;
        }
        lastPushCongratulateRecordTimeMap.put(type, recordTime);
        return true;
    }

    private long getLastPushCongratulateRecordTime(int mammonType) {
        if (lastPushCongratulateRecordTimeMap.containsKey(mammonType)) {
            return lastPushCongratulateRecordTimeMap.get(mammonType);
        }
        return 0;
    }

    /**
     * 记录财神簿恭贺时间点
     */
    public void addMammonCongratulate(int type, long recordTime, long congratulateTime) {
        MammonCongratulateTime mammonCongratulateTime = userMammon.setCongratulateTime(type, recordTime, congratulateTime);
        syncUserMammonCongratulate(mammonCongratulateTime);
    }

    public UserMammon getUserMammon() {
        return userMammon;
    }

    public MammonEffectResult isMammonSkillEffect(int skillType, long value) {
        MammonEffectResult result = new MammonEffectResult();
        result.setValue(value);
        if (null == userMammon) {
            return result;
        }
        SkillInfo skillInfo = SkillMgr.getSkillInfo(userMammon.getMammonSkillId());
        if (null == skillInfo) {
            return result;
        }
        if (skillInfo.getType() != skillType) {
            return result;
        }
        if (userMammon.getEffectTimes() >= skillInfo.getParamList().get(2)) {
            result.setOverMaxEffectTimes(true);
            return result;
        }
        int randomValue = threadSafeRandom.next(0, 1000);
        if (randomValue > skillInfo.getParamList().get(1)) {
            return result;
        }
        double addition = skillInfo.getParamList().get(0);
        result.setEffectMammonSkill(userMammon.getMammonSkillId());
        if (skillInfo.getType() == eSkillType.MammonRankWorshipAddIngots.getValue()) {
            result.setValue((int) (value + addition));
        } else {
            result.setValue((int) Math.ceil(addition / 1000 * value));
        }
        userMammon.setEffectTimes(userMammon.getEffectTimes() + 1);
        syncUserMammon();
        return result;
    }

    public boolean isInCongratulateCD(int type) {
        MammonCongratulateTime congratulateTime = userMammon.getCongratulateTime(type);
        if (congratulateTime == null) {
            return false;
        }
        long time = congratulateTime.getCongratulateTime();
        int days = DateHelper.calc2DateTDOADays(new Date(time * 1000), new Date()) - 1;
        if (days > 1) {
            return false;
        }
        return true;
    }
}
